package personnal.blogprinter.htmlparser;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.EmptyStackException;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;

import com.lowagie.text.BadElementException;
import com.lowagie.text.DocListener;
import com.lowagie.text.DocumentException;
import com.lowagie.text.ElementTags;
import com.lowagie.text.ExceptionConverter;
import com.lowagie.text.Image;
import com.lowagie.text.factories.ElementFactory;
import com.lowagie.text.html.HtmlTagMap;
import com.lowagie.text.html.HtmlTags;
import com.lowagie.text.html.SAXmyHtmlHandler;

public class SaxHtmlHandler extends SAXmyHtmlHandler {

	private static final Logger logger = Logger.getLogger(SaxHtmlHandler.class);

	private static final int DEFAULT_RETRYCOUNT = 3;
	private static final long SLEEP_BEFORE_RETRY = 2000L;

	private long sleepBeforeRetry = SLEEP_BEFORE_RETRY;

	public SaxHtmlHandler(DocListener document) {
		super(document, new HtmlTagMap());
	}

	@Override
	public void startElement(String uri, String lname, String name, Attributes attrs) {
		if (HtmlTags.ANCHOR.equals(name) || HtmlTags.ROW.equals(name)) {
			return;
		}
		super.startElement(uri, lname, name, attrs);
	}

	public void handleStartingTags(String name, Properties attributes) {
		// images
		if (ElementTags.IMAGE.equals(name)) {
			int retryCount = DEFAULT_RETRYCOUNT;
			do {
				try {
					Image img = getImage(attributes);
					try {
						addImage(img);
						return;
					} catch (EmptyStackException ese) {
						// if there is no element on the stack, the Image is
						// added to the document
						try {
							document.add(img);
						} catch (DocumentException de) {
							throw new ExceptionConverter(de);
						}
						return;
					}
				} catch (IOException e) {
					retryCount--;
					if (retryCount == 0) {
						logger.warn("Error received while downloading image "
								+ attributes.getProperty(ElementTags.URL)
								+ ", giving up ...", e); // throw new
														// ExceptionConverter(e);
						return;
					} else {
						logger.warn("Error received while downloading image "
								+ attributes.getProperty(ElementTags.URL)
								+ ", retrying ...", e);
						try {
							Thread.sleep(sleepBeforeRetry);
						} catch (InterruptedException e1) {
							logger.warn("Can't sleep between retry", e1);
						}
					}
				} catch (Exception e) {
					throw new ExceptionConverter(e);
				}
			} while (retryCount > 0);
		}
		try {
			super.handleStartingTags(name, attributes);
		} catch (Exception e) {
			throw new ExceptionConverter(e);
		}
	}

	protected Image getImage(Properties attributes) throws BadElementException,
			MalformedURLException, IOException {
		return ElementFactory.getImage(attributes);
	}

	@Override
	public void endElement(String uri, String lname, String name) {
		if (HtmlTags.ANCHOR.equals(name) || HtmlTags.ROW.equals(name)) {
			return;
		}
		super.endElement(uri, lname, name);
	}

	public void setSleepBeforeRetry(long sleepBeforeRetry) {
		this.sleepBeforeRetry = sleepBeforeRetry;
	}
}